'use strict'

const {app: electronApp} = require('electron')
const {autoUpdater} = require("electron-updater")
const {is} = require('ee-core/utils')
const {logger} = require('ee-core/log')
const {getConfig} = require('ee-core/config')
const {getMainWindow, setCloseAndQuit} = require('ee-core/electron')
const {appService} = require('../../service/app')

/**
 * 自动升级插件
 */
class AutoUpdaterService {
    /**
     * 创建
     */
    create() {
        logger.info('[autoUpdater] load')
        const cfg = getConfig().autoUpdater
        if ((is.windows() && cfg.windows) || (is.macOS() && cfg.macOS) || (is.linux() && cfg.linux)) {
            // continue
        } else {
            return
        }

        let isForceUpdate = cfg.force
        //检查客户端用户配置(系统优先级大于客户端用户)
        if (!isForceUpdate) {
            const userDefined = appService.appAutoUpdates
            if (userDefined != null && userDefined === 'autoupdate') {
                isForceUpdate = true
            }
        }

        const status = {
            error: -1,
            available: 1,
            noAvailable: 2,
            downloading: 3,
            downloaded: 4
        }

        const version = electronApp.getVersion()
        logger.info('[autoUpdater] current version: ', version)

        // 设置下载服务器地址
        let server = cfg.options.url
        let lastChar = server.substring(server.length - 1)
        server = lastChar === '/' ? server : (server + "/")
        cfg.options.url = server

        // 是否后台自动下载
        autoUpdater.autoDownload = !!isForceUpdate

        try {
            autoUpdater.setFeedURL(cfg.options)
        } catch (error) {
            logger.error('[autoUpdater] setFeedURL error : ', error)
        }

        autoUpdater.on('checking-for-update', () => {
            //sendStatusToWindow('Checking for updates...');
        })

        autoUpdater.on('update-available', (info) => {
            info.status = status.available
            info.desc = 'There are valid updates.'
            this.sendStatusToWindow(info)
        })

        autoUpdater.on('update-not-available', (info) => {
            info.status = status.noAvailable
            info.desc = 'No valid updates.'
            this.sendStatusToWindow(info)
        })

        autoUpdater.on('error', (err) => {
            let info = {
                status: status.error,
                desc: err
            }
            this.sendStatusToWindow(info)
        })

        autoUpdater.on('download-progress', (progressObj) => {
            let percentNumber = parseInt(progressObj.percent)
            let totalSize = this.bytesChange(progressObj.total)
            let transferredSize = this.bytesChange(progressObj.transferred)
            let text = 'Downloaded ' + percentNumber + '%'
            text = text + ' (' + transferredSize + "/" + totalSize + ')'

            let info = {
                status: status.downloading,
                desc: text,
                percentNumber: percentNumber,
                totalSize: totalSize,
                transferredSize: transferredSize
            }
            logger.info('[autoUpdater] progress: ', text)
            this.sendStatusToWindow(info)
        })

        autoUpdater.on('update-downloaded', (info) => {
            info.status = status.downloaded
            info.desc = 'Download completed'
            this.sendStatusToWindow(info)
            //这里标记窗口已关闭
            setCloseAndQuit(true)
            autoUpdater.quitAndInstall()
        })
        // 是否检查更新
        if (isForceUpdate) {
            this.checkUpdate(null, 'sys')
        }
    }

    /**
     * 检查更新
     */
    async checkUpdate(senderWindow = null, senderName = null) {
        this.callBrowserWindow = senderWindow || getMainWindow()
        this.callSenderName = senderName || 'main'
        return await autoUpdater.checkForUpdates()
    }

    /**
     * 下载更新
     */
    download() {
        autoUpdater.downloadUpdate()
    }

    /**
     * 向前端发消息
     */
    sendStatusToWindow(content = {}) {
        content.senderName = this.callSenderName
        const textJson = JSON.stringify(content)
        const channel = 'app:updater'
        this.callBrowserWindow.webContents.send(channel, textJson)
    }

    /**
     * 单位转换
     */
    bytesChange(limit) {
        let size = ""
        if (limit < 0.1 * 1024) {
            size = limit.toFixed(2) + "B"
        } else if (limit < 0.1 * 1024 * 1024) {
            size = (limit / 1024).toFixed(2) + "KB"
        } else if (limit < 0.1 * 1024 * 1024 * 1024) {
            size = (limit / (1024 * 1024)).toFixed(2) + "MB"
        } else {
            size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"
        }

        let sizeStr = size + ""
        let index = sizeStr.indexOf(".")
        let dou = sizeStr.substring(index + 1, index + 3)
        if (dou == "00") {
            return sizeStr.substring(0, index) + sizeStr.substring(index + 3, index + 5)
        }

        return size
    }
}

AutoUpdaterService.toString = () => '[class AutoUpdaterService]'
module.exports = {
    autoUpdaterService: new AutoUpdaterService()
}